<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
  <title></title>
 </head>

 <body>
  <div id="stage" style="width:480px;height:650px;margin:0px auto;">
	<canvas id="canvas" width="480" height="650"></canvas>
  </div>
  <script>
	//定义宽和高
	var WIDTH=480,HEIGHT=650;
	var score = 0,life=3;
	//定义状态
	var START = 0;
	var STARTING = 1;
	var RUNNING = 2;
	var PAUSE = 3;
	var GAME_OVER = 4;

	/**
	 * state表示游戏的状态
	 * 取值必须为以上五种之一
	 */
	var state = START;
	
	//获取数据
	var canvas = document.getElementById("canvas");
	ctx = canvas.getContext("2d");

	//创建图像对象用来表示天空、英雄、敌人、版权
	var bg = new Image();
	bg.src="img/background.png";

	var copyright = new Image();
	copyright.src="img/shoot_copyright.png";

	var pause = new Image();
	pause.src="img/game_pause_nor.png";

	var l = [];
	l[0] = new Image();
	l[0].src="img/game_loading1.png";
	l[1] = new Image();
	l[1].src="img/game_loading2.png";
	l[2] = new Image();
	l[2].src="img/game_loading3.png";
	l[3] = new Image();
	l[3].src="img/game_loading4.png";
	//创建英雄图像数组
	var h = [];
	h[0] = new Image();
	h[0].src="img/hero1.png";
	h[1] = new Image();
	h[1].src="img/hero2.png";
	h[2] = new Image();
	h[2].src="img/hero_blowup_n1.png";
	h[3] = new Image();
	h[3].src="img/hero_blowup_n2.png";
	h[4] = new Image();
	h[4].src="img/hero_blowup_n3.png";
	h[5] = new Image();
	h[5].src="img/hero_blowup_n4.png";
	//创建子弹图像
	var b = new Image();
	b.src="img/bullet1.png";
	
	//为canvas添加事件(onclick,onmousemove,onmoseout)
	canvas.onclick=function(){
		if(state == START){
			state = STARTING;
		}
	}
	/**
	 *鼠标移动事件
	 *处理 hero与鼠标的位置
	 */
	canvas.onmousemove = function(e){
		var x = e.offsetX;
		var y = e.offsetY;

		hero.x = x - HERO.width / 2;
		hero.y = y - HERO.height / 2;
	}

	canvas.onmouseout = function(e){
		if(state == RUNNING){
			state = PAUSE;
		}
	}

	canvas.onmouseover = function(e){
		if(state == PAUSE){
			state = RUNNING;
		}
	}

	//数据对象
	var SKY = {image:bg,width:480,height:650,speed:40};
	var LOADING = {frames:l,width:186,height:38,x:0,y:HEIGHT-38,speed:5};
	var HERO = {frames:h,baseFrameCount:2,width:99,height:124,speed:100};
	var BULLET = {image:b,width:9,height:21};
	//保存由hero发射的所有子弹
	var bullets = [];

	//业务对象
	
	/**
	 * 子弹对象
	 */
	var Bullet = function(config,x,y){
		this.width = config.width;
		this.height = config.height;
		this.frame = config.image;
		this.x = x;
		this.y = y;

		this.move = function(){
			this.y -= 2;
		}

		this.paint = function(ctx){
			ctx.drawImage(this.frame,this.x,this.y);
		}
	}
	
	/**
	 * 创建飞机业务对象
	 */
	var Hero = function(config){
		this.frames = config.frames;
		this.frameIndex = 0;
		this.baseFrameCount=config.baseFrameCount;
		this.width=config.width;
		this.height=config.height;
		this.speed=1000/config.speed;
		this.lastTime = 0;
		this.x = (WIDTH - this.width) / 2;
		this.y = HEIGHT - this.height - 30;
		
		this.step = function(){
			var currentTime = new Date().getTime();
			if(currentTime - this.lastTime >= this.speed){
				this.frame = this.frames[this.frameIndex % this.baseFrameCount];
				this.frameIndex ++;
				this.lastTime = new Date().getTime();
			}
		}

		this.paint = function(ctx){
			ctx.drawImage(this.frame,this.x,this.y);
		}
		
		this.shootLastTime=0;
		//发射子弹的间隔
		this.shootInterval = 200;
		//处理子弹的发射
		this.shoot = function(){
			var currentTime = new Date().getTime();
			if(currentTime - this.shootLastTime >= this.shootInterval){
				//到达时间间隔，可以发射子弹
				var bullet = new Bullet(BULLET,this.x+45,this.y);
				bullets[bullets.length] = bullet;

				//console.log("子弹数量:"+bullets.length);
				this.shootLastTime = new Date().getTime();
			}
		}
	}

	/**
	 * 加载的业务对象
	 * config:表示加载的数据对象
	 */
	var Loading = function(config){
		this.speed = 1000 / config.speed;
		this.lastTime = 0;
		this.frame=null;
		this.frameIndex = 0;

		//更换loading图像
		this.step = function(){
			var currentTime = new Date().getTime();
			if(currentTime - this.lastTime >= this.speed){
				//获取不同的图像config.frames中的元素给frame
				this.frame = config.frames[this.frameIndex];
				this.frameIndex ++;
				if(this.frameIndex >= 4){
					//更新状态
					state = RUNNING;
				}
				this.lastTime = new Date().getTime();
			}
			
		}
		/**
		 * 绘制不同的图像到canvas上
		 */
		this.paint = function(ctx){
			ctx.drawImage(this.frame,config.x,config.y);
		}
	}

	/**
	 * 天空的业务对象
	 * config:表示天空的数据对象
	 */
	var Sky = function(config){
		this.bg = config.image; //设置背景图像
		this.width=config.width;
		this.height = config.height;
		this.speed = 1000 / config.speed;
		this.x1 = 0;
		this.y1 = 0;
		this.x2 = 0;
		this.y2 = -this.height;
		this.lastTime = 0; //上一次执行动作时间的毫秒数

		/**
		 * 移动背景纵坐标
		 */
		this.step = function(){
			//判断是否到达天空移动的时间
			//获取当前时间的毫秒数
			var currentTime = new Date().getTime();
			if(currentTime - this.lastTime >= this.speed){
				// y1++ , y2++
				this.y1++;
				this.y2++;
				this.lastTime = new Date().getTime();
			} 

			//判断y1、y2 是否超出范围
			if(this.y1 >= this.height){
				this.y1 = -this.height;
			}
			if(this.y2 >= this.height){
				this.y2 = -this.height;
			}
		}
		
		/**
		 * 绘制天空图像
		 *ctx : canvas 绘图上下文
		 */
		this.paint = function(ctx){
			ctx.drawImage(this.bg,this.x1,this.y1);
			ctx.drawImage(this.bg,this.x2,this.y2);
		}
	}

	//创建业务对象
	var sky = new Sky(SKY);
	var loading = new Loading(LOADING);
	var hero = new Hero(HERO);

	/**
	 * 绘制各个组件
	 */
	function paintComponent(){
		//绘制子弹
		for(var i=0;i<bullets.length ; i ++){
			var bullet = bullets[i];
			bullet.paint(ctx);
		}
		
		//将绘制hero的方法移动至此
		hero.paint(ctx);

		ctx.font = "20px 微软雅黑";
		ctx.fillText("SCORE:"+score,10,20);
		ctx.fillText("LIFE:"+life,400,20)
	}
	
	/**
	 * 让所有的组件动起来(更新y坐标)
	 */
	function stepComponent(){
		for(var i=0;i<bullets.length ; i ++){
			bullets[i].move();
		}
	}

	//定义计时器，固定刷新频率为 1000 / 100
	setInterval(function(){
		switch(state){
			case START:
				//天空在移动
				sky.step();
				sky.paint(ctx);
				//绘制copyright
				var x =  (WIDTH - copyright.naturalWidth) / 2;
				var y =  (HEIGHT - copyright.naturalHeight) / 2;
				ctx.drawImage(copyright,x,y);
				break;
			case STARTING:
				//准备开始
				sky.step();
				sky.paint(ctx);
				
				loading.step();
				loading.paint(ctx);
				break;
			case RUNNING:
				//游戏进行
				sky.step();
				sky.paint(ctx);
				
				hero.step();
				hero.paint(ctx);
				hero.shoot();
				stepComponent();
				//绘制所有的组件
				paintComponent();
				break;
			case PAUSE:
				//暂停
				sky.step();
				sky.paint(ctx);
				paintComponent();
				ctx.drawImage(pause,(WIDTH-pause.width)/2,(HEIGHT-pause.height)/2);
				break;
			case GAME_OVER:
				//游戏结束
				break;
		}
	},1000/100);

  </script>
 </body>
</html>
